home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
27KB
|
1,161 lines
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "mutt.h"
#include "mutt_curses.h"
#include "rfc1524.h"
#include "keymap.h"
#include "mime.h"
#include "state.h"
#include "parse.h"
#ifdef _PGPPATH
#include "pgp.h"
#endif
typedef void handler_f (BODY *, STATE *);
typedef handler_f *handler_t;
int Index_hex[128] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1,
-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};
int Index_64[128] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
};
void mutt_decode_xbit (STATE *s, long len, int istext)
{
int linelen;
char buffer[LONG_STRING];
if (istext)
{
while (len > 0)
{
if (fgets (buffer, LONG_STRING, s->fpin) == 0) return;
linelen = strlen (buffer);
len -= linelen;
if (linelen >= 2 && buffer[linelen-2] == '\r')
{
buffer[linelen-2] = '\n';
buffer[linelen-1] = 0;
}
if (s->prefix) state_puts (s->prefix, s);
state_puts (buffer, s);
}
}
else
mutt_copy_bytes (s->fpin, s->fpout, len);
}
void mutt_decode_quoted (STATE *s, long len, int istext)
{
char *c, buffer[LONG_STRING];
int ch, soft = 0;
while (len > 0)
{
if (fgets (buffer, LONG_STRING, s->fpin) == NULL)
{
dprint (1, (debugfile, "mutt_decode_quoted: unexpected EOF.\n"));
state_puts ("[-- Error: unexpected end of file! --]\n", s);
break;
}
c = buffer;
len -= strlen (buffer);
if (s->prefix && !soft) state_puts (s->prefix, s);
soft = 0;
while (*c)
{
if (*c == '=')
{
if (c[1] == '\n' || c[1] == '\r' || c[1] == ' ' || c[1] == '\t')
{
/* Skip whitespace at the end of the line since MIME does not
* allow for it
*/
soft = 1;
break;
}
ch = hexval ((int) c[1]) << 4;
ch |= hexval ((int) c[2]);
state_putc (ch, s);
c += 3;
}
else if (istext && c[0] == '\r' && c[1] == '\n')
{
state_putc ('\n', s);
break;
}
else
{
state_putc (*c, s);
c++;
}
}
}
}
void mutt_decode_base64 (STATE *s, long len, int istext)
{
char buf[5];
int c1, c2, c3, c4, ch, cr = 0, i;
buf[4] = 0;
if (s->prefix) state_puts (s->prefix, s);
while (len > 0)
{
for (i = 0 ; i < 4 && len > 0 ; len--)
{
if ((ch = fgetc (s->fpin)) == EOF)
return;
if (!ISSPACE (ch))
buf[i++] = ch;
}
if (i != 4)
return; /* didn't get a multiple of four chars! */
c1 = base64val ((int) buf[0]);
c2 = base64val ((int) buf[1]);
ch = (c1 << 2) | (c2 >> 4);
if (cr && ch != '\n') state_putc ('\r', s);
cr = 0;
if (istext && ch == '\r')
cr = 1;
else
{
state_putc (ch, s);
if (ch == '\n' && s->prefix) state_puts (s->prefix, s);
}
if (buf[2] == '=')
break;
c3 = base64val ((int) buf[2]);
ch = ((c2 & 0xf) << 4) | (c3 >> 2);
if (cr && ch != '\n')
state_putc ('\r', s);
cr = 0;
if (istext && ch == '\r')
cr = 1;
else
{
state_putc (ch, s);
if (ch == '\n' && s->prefix)
state_puts (s->prefix, s);
}
if (buf[3] == '=') break;
c4 = base64val ((int) buf[3]);
ch = ((c3 & 0x3) << 6) | c4;
if (cr && ch != '\n')
state_putc ('\r', s);
cr = 0;
if (istext && ch == '\r')
cr = 1;
else
{
state_putc (ch, s);
if (ch == '\n' && s->prefix)
state_puts (s->prefix, s);
}
}
}
/* ----------------------------------------------------------------------------
* A (not so) minimal implementation of RFC1563.
*/
#define IndentSize (4)
enum { RICH_PARAM=0, RICH_BOLD, RICH_UNDERLINE, RICH_ITALIC, RICH_NOFILL,
RICH_INDENT, RICH_INDENT_RIGHT, RICH_EXCERPT, RICH_CENTER, RICH_FLUSHLEFT,
RICH_FLUSHRIGHT, RICH_COLOR, RICH_LAST_TAG };
static struct {
const char *tag_name;
int index;
} EnrichedTags[] = {
{ "param", RICH_PARAM },
{ "bold", RICH_BOLD },
{ "italic", RICH_ITALIC },
{ "underline", RICH_UNDERLINE },
{ "nofill", RICH_NOFILL },
{ "excerpt", RICH_EXCERPT },
{ "indent", RICH_INDENT },
{ "indentright", RICH_INDENT_RIGHT },
{ "center", RICH_CENTER },
{ "flushleft", RICH_FLUSHLEFT },
{ "flushright", RICH_FLUSHRIGHT },
{ "flushboth", RICH_FLUSHLEFT },
{ "color", RICH_COLOR },
{ "x-color", RICH_COLOR },
{ NULL, -1 }
};
struct enriched_state
{
char *buffer;
char *line;
char *param;
size_t buff_len;
size_t line_len;
size_t line_used;
size_t indent_len;
size_t word_len;
size_t buff_used;
size_t param_len;
int tag_level[RICH_LAST_TAG];
int WrapMargin;
STATE *s;
};
static void enriched_wrap (struct enriched_state *stte)
{
int x;
int extra;
if (stte->line_len)
{
if (stte->tag_level[RICH_CENTER] || stte->tag_level[RICH_FLUSHRIGHT])
{
/* Strip trailing white space */
size_t y = stte->line_used - 1;
while (y && ISSPACE (stte->line[y]))
{
stte->line[y] = '\0';
y--;
stte->line_used--;
stte->line_len--;
}
if (stte->tag_level[RICH_CENTER])
{
/* Strip leading whitespace */
y = 0;
while (stte->line[y] && ISSPACE (stte->line[y]))
y++;
if (y)
{
size_t z;
for (z = y ; z <= stte->line_used; z++)
{
stte->line[z - y] = stte->line[z];
}
stte->line_len -= y;
stte->line_used -= y;
}
}
}
extra = stte->WrapMargin - stte->line_len - stte->indent_len -
(stte->tag_level[RICH_INDENT_RIGHT] * IndentSize);
if (extra > 0)
{
if (stte->tag_level[RICH_CENTER])
{
x = extra / 2;
while (x)
{
state_putc (' ', stte->s);
x--;
}
}
else if (stte->tag_level[RICH_FLUSHRIGHT])
{
x = extra-1;
while (x)
{
state_putc (' ', stte->s);
x--;
}
}
}
state_puts (stte->line, stte->s);
}
state_putc ('\n', stte->s);
stte->line[0] = '\0';
stte->line_len = 0;
stte->line_used = 0;
stte->indent_len = 0;
if (stte->s->prefix)
{
state_puts (stte->s->prefix, stte->s);
stte->indent_len += strlen (stte->s->prefix);
}
if (stte->tag_level[RICH_EXCERPT])
{
x = stte->tag_level[RICH_EXCERPT];
while (x)
{
if (stte->s->prefix)
{
state_puts (stte->s->prefix, stte->s);
stte->indent_len += strlen (stte->s->prefix);
}
else
{
state_puts ("> ", stte->s);
stte->indent_len += strlen ("> ");
}
x--;
}
}
else
stte->indent_len = 0;
if (stte->tag_level[RICH_INDENT])
{
x = stte->tag_level[RICH_IN